﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.Foundation;

using Windows.ApplicationModel.DataTransfer;

namespace CompleteReader.Utilities
{
    class SharingHelper
    {
        private static SharingHelper _Instance;
        
        // We will share either one of these.
        StorageFile _FileToShare;
        IList<Data.RecentItem> _RecentItems;

        private string _ErrorMessage = "An Error Occured";
        /// <summary>
        /// Set this if you can not satisfy the share request (e.g. when no files are selected in a list)
        /// so that the error message displayed to the user is meaningful
        /// </summary>
        public String ErrorMessage { set { _ErrorMessage = value; } }

        public delegate StorageFile RetrieveSharingStorageFileHandler();
        public event RetrieveSharingStorageFileHandler RetrieveSharingStorageFile;

        public delegate IList<Data.RecentItem> RetrieveSharingRecentItemsHandler();
        public event RetrieveSharingRecentItemsHandler RetrieveSharingRecentItems;

        public delegate Task SaveDocumentDelegate();
        public SaveDocumentDelegate _Saver = null;
        public SaveDocumentDelegate DocumentSaver
        {
            set { _Saver = value; }
        }

        public AutoSaveHelper SaveHelper { get; set; }



        public static SharingHelper GetSharingHelper()
        {
            if (_Instance == null)
            {
                _Instance = new SharingHelper();
            }
            return _Instance;
        }

        private SharingHelper()
        {
            DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
            dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(this.ShareTextHandler);
        }

        private void ShareTextHandler(DataTransferManager sender, DataRequestedEventArgs e)
        {
            AnalyticsHandler.CURRENT.SendEvent("[Viewer] Share clicked from Viewer");

            _FileToShare = null;
            _RecentItems = null;

            if (RetrieveSharingStorageFile != null)
            {
                _FileToShare = RetrieveSharingStorageFile();
            }
            if (RetrieveSharingRecentItems != null)
            {
                _RecentItems = RetrieveSharingRecentItems();
            }


            DataRequest request = e.Request;
            Windows.ApplicationModel.Resources.ResourceLoader loader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();

            if (_FileToShare != null || _RecentItems != null)
            {
                if (_FileToShare != null)
                {
                    request.Data.Properties.Title = string.Format(loader.GetString("Sharing_SignleDocument_Title"), Settings.Settings.DisplayName, _FileToShare.Name);
                }
                else if (_RecentItems != null)
                {
                    if (_RecentItems.Count == 1)
                    {
                        request.Data.Properties.Title = string.Format(loader.GetString("Sharing_SignleDocument_Title"), Settings.Settings.DisplayName, _RecentItems[0].DocumentName);
                    }
                    else
                    {
                        request.Data.Properties.Title = string.Format(loader.GetString("Sharing_MultipleDocuments_Title"), Settings.Settings.DisplayName);
                    }
                }
                request.Data.Properties.ApplicationName = Settings.Settings.DisplayName;
                string emailSignature = Settings.Settings.EmailSignature;
                if (emailSignature.Length > 0)
                {
                    request.Data.SetText(emailSignature);
                }
                request.Data.Properties.FileTypes.Add("*.pdf");
                request.Data.SetDataProvider(StandardDataFormats.StorageItems, new DataProviderHandler(this.OnDeferredFileRequestedHandler));
            }
            else
            {
                e.Request.FailWithDisplayText(_ErrorMessage);
            }
        }

        private async void OnDeferredFileRequestedHandler(DataProviderRequest request)
        {
            DataProviderDeferral deferral = request.GetDeferral();

            if (_FileToShare == null && _RecentItems == null)
            {
                return;
            }

            // Make sure to always call Complete when finished with the deferral.
            try
            {
                if (_FileToShare != null)
                {
                    // pause auto saver
                    if (SaveHelper != null)
                    {
                        SaveHelper.IsPaused = true;
                    }
                    IReadOnlyList<StorageFile> storageFileList = new List<StorageFile>() { _FileToShare };
                    if (_Saver != null)
                    {
                        await _Saver();
                    }

                    request.SetData(storageFileList);
                    EnableSavingAfterDelay();

                }
                else if (_RecentItems != null)
                {
                    Data.RecentItemsData recentItemsData = await Data.RecentItemsData.GetItemSourceAsync(null);
                    List<StorageFile> storageItems = new List<StorageFile>();
                    foreach (Data.RecentItem recentIem in _RecentItems)
                    {
                        StorageFile file = await recentItemsData.GetRecentFileAsync(recentIem);
                        storageItems.Add(file);
                    }
                    IReadOnlyList<StorageFile> rol = storageItems as IReadOnlyList<StorageFile>;
                    request.SetData(rol);
                }
            }
            finally
            {
                deferral.Complete();
            }
        }

        private async void EnableSavingAfterDelay()
        {
            try
            {
                await Task.Delay(3000);
                if (SaveHelper != null)
                {
                    SaveHelper.IsPaused = false;
                }
            }
            catch (Exception)
            {

            }
        }
    }
}
